package cn.hinglo.permission.service;

import cn.hinglo.common.utils.SysCommonKit;
import cn.hinglo.permission.bean.model.*;
import cn.hutool.core.util.StrUtil;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.SqlPara;
import org.springframework.stereotype.Service;

import java.util.*;


/**
 * @author HingLo
 * @createTime: 2018/3/1
 * @description: 权限管理的服务层
 */
@Service
public class PermissionService {

    /**
     * 权限列表
     *
     * @param page 页码
     * @param size 大小
     * @return 权限集合
     */
    public Map<String, Object> listPermissionService(Integer page, Integer size) {
        SqlPara sql = Db.getSqlPara("sys.listPermission");
        Page<Record> list = Db.paginate(page, size, sql);
        return SysCommonKit.pageKit(list.getTotalRow(), SysCommonKit.recordToMapKit(list.getList()));
    }

    /**
     * 获取全部权限
     *
     * @return 返回结果
     */
    public List<?> allPermissionService() {
        SqlPara sql = Db.getSqlPara("sys.allPermission");
        return SysCommonKit.recordToMapKit(Db.find(sql));
    }

    /**
     * 添加权限
     *
     * @param permission 权限对象信息
     * @return 操作结果
     */
    public boolean addPermissionService(Permission permission) {
        String url = permission.getUrl();
        // 操作去掉url中的空格
        permission.setUrl(url.trim());
        permission.setDate(new Date());
        return permission.save();

    }

    /**
     * 删除权限
     *
     * @param id 权限的唯一ID
     * @return 操作结果
     */
    public boolean deletePermissionService(String id) {
        return StrUtil.isNotBlank(id) && Permission.DAO.deleteById(id);
    }

    /**
     * 更新权限信息
     *
     * @param permission 包含了权限ID的权限对象集合
     * @return 更新结果
     */
    public boolean changePermissionService(Permission permission) {
        return permission.update();
    }

    /***
     * 添加用户的角色 <br>
     *
     * @param userId 用户的Id
     * @param roleId roleId 集合
     * @return 授权结果
     */
    public boolean addUserRoleService(String userId, Set<Long> roleId) {
        // 授权角色时候，角色不能为null
        if (StrUtil.isBlank(userId) || roleId.size() < 1) {
            return false;
        }
        // 删除原来的角色sql
        String deleteSql = Db.getSql("sys.deleteUserRole");
        List<UserRole> userRoleList = new ArrayList<>();
        for (Long s : roleId) {
            UserRole userRole = new UserRole();
            userRole.setRoleId(s);
            userRole.setUserId(userId);
            userRoleList.add(userRole);
        }
        // 在事物中执行
        return Db.tx(() -> Db.delete(deleteSql, userId) > 0 && Db.batchSave(userRoleList, userRoleList.size()).length > 0);
    }

    /***
     * 删除用户
     *
     * @param id 用户唯一编号
     * @return 返回删除结果
     */
    public boolean deleteUserService(String id) {
        return User.DAO.deleteById(id);
    }

    /**
     * 给指定的角色授权
     *
     * @param menuId       菜单Id集合
     * @param permissionId 权限Id集合
     * @param roleId       角色Id
     * @return 授权结果
     */
    public boolean addRolePermissionService(Set<Long> menuId, Set<Long> permissionId, Long roleId) {

        // 删除角色菜单的sql语句
        String menuSql = Db.getSql("sys.deleteRolePermission");
        // 删除角色权限的sql
        String permissionSql = Db.getSql("sys.deleteRoleMenu");

        List<RoleMenu> roleMenuList = new ArrayList<>();
        // 组装菜单权限对象
        for (Long s : menuId) {
            RoleMenu roleMenu = new RoleMenu();
            roleMenu.setMid(s);
            roleMenu.setRoleId(roleId);
            roleMenuList.add(roleMenu);
        }
        // 批量添加业务权限
        List<RolePermission> rolePermissionList = new ArrayList<>();
        // 组装菜单权限对象
        for (Long s : permissionId) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setPermissionId(s);
            rolePermission.setRoleId(roleId);
            rolePermissionList.add(rolePermission);
        }
        return Db.tx(() -> Db.delete(menuSql, roleId) > 0 && Db.delete(permissionSql, roleId) > 0
                && Db.batchSave(rolePermissionList, rolePermissionList.size()).length > 0
                && Db.batchSave(roleMenuList, roleMenuList.size()).length > 0);

    }

    /**
     * 查询全部的角色列表
     *
     * @return 角色列表
     */
    public List<Role> listRoleListService() {
        String sql = Db.getSql("sys.listRoleList");
        return Role.DAO.find(sql);

    }

    /**
     * 给系统中添加角色
     *
     * @param role 角色对象
     * @return 操作结果
     */
    public boolean addRoleService(Role role) {
        role.setDate(new Date());
        return StrKit.notBlank(role.getName(), role.getContent()) && role.save();
    }

    /**
     * 删除指定的角色
     *
     * @param id 角色的唯一Id
     * @return 操作结果
     */
    public boolean deleteRoleService(String id) {
        return StrKit.notBlank(id) && Role.DAO.deleteById(id);

    }

    /**
     * 根据角色来查询权限
     *
     * @param id 角色Id
     * @return 权限列表
     */
    public List<?> listRolePermissionService(String id) {
        if (StrUtil.isBlank(id)) {
            return null;
        }
        String sql = Db.getSql("sys.listRolePermission");
        return SysCommonKit.recordToMapKit(Db.find(sql, id));
    }

    /****
     * 全部的菜单信息
     *
     * @param page 页码
     * @param size 大小
     * @return 返回结果
     */
    public Map<String, Object> listMenuService(Integer page, Integer size) {
        SqlPara sql = Db.getSqlPara("sys.listMenu");
        Page list = Menu.DAO.paginate(page, size, sql);
        return SysCommonKit.pageKit(list.getTotalRow(), list.getList());
    }

    /***
     * 全部菜单递归好的信息
     *
     * @return 返回递归好的信息
     */
    public List<Map<String, Object>> allMenuService() {
        SqlPara sql = Db.getSqlPara("sys.listMenu");
        List<Record> list = Db.find(sql);
        return SysCommonKit.recordToMapKit(SysCommonKit.createTreeMenuKit(list));
    }

    /**
     * 查询全部的一级菜单
     *
     * @return 返回结果
     */
    public List<?> fidMenuService() {
        String sql = Db.getSql("sys.fidMenu");
        List<Record> list = new ArrayList<>();
        // 添加默认的一级菜单
        list.add(new Record().set("id", 0).set("name", "一级菜单"));
        // 追加全部菜单到后面
        list.addAll(Db.find(sql));
        return SysCommonKit.recordToMapKit(list);
    }

    /**
     * 添加菜单
     *
     * @param menu 菜单对象
     * @return 操作结果
     */
    public boolean addMenuService(Menu menu) {
        menu.setDate(new Date());
        return menu.save();
    }

    /***
     * 删除指定的菜单
     *
     * @param id 菜单唯一ID
     * @return 操作结果
     */
    public boolean deleteMenuService(String id) {
        if (StrUtil.isBlank(id)) {
            return false;
        }
        String sql = Db.getSql("sys.deleteMenu");
        return Db.delete(sql, id, id) > 0;
    }

    /**
     * 更新菜单信息
     *
     * @param menu 修改后的菜单信息
     * @return 操作结果
     */
    public boolean updateMenuService(Menu menu) {
        return menu.update();
    }

    /***
     * 用户角色查询
     *
     * @return 返回结果
     */
    public Map<String, ?> listUserRoleService(int page, int size) {
        SqlPara sql = Db.getSqlPara("sys.listUserRole");
        Page<Record> list = Db.paginate(page, size, sql);
        return SysCommonKit.pageKit(list.getTotalRow(), SysCommonKit.recordToMapKit(list.getList()));
    }

    /**
     * @return 全部服务
     */
    public List<?> listService() {
        String sql = Db.getSql("sys.listService");
        return SysCommonKit.recordToMapKit(Db.find(sql));
    }

    /**
     * 添加服务
     *
     * @param service 服务对象
     * @return 返回结果
     */
    public boolean addService(Services service) {
        if (!StrKit.notBlank(service.getUrl(), service.getName())) {
            return false;
        }
        service.setDate(new Date());
        return service.save();
    }

    /***
     * 修改服务信息
     *
     * @param service 服务信息
     * @return 返回结果
     */
    public Object updateService(Services service) {
        return service.update();
    }

    /**
     * 通过ID 删除服务信息
     *
     * @param id id
     * @return 返回删除结果
     */
    public boolean deleteService(Integer id) {
        return Services.DAO.deleteById(id);
    }
}
